package com.ybt.router.client;

import java.util.Properties;
import java.util.UUID;

import org.apache.log4j.Logger;

import com.ybt.configration.YBTRuntimeConfiguration;
import com.ybt.router.core.cache.SynResponse;
import com.ybt.router.core.cache.SynResponsePool;
import com.ybt.router.core.manager.RouterTypeManager;
import com.ybt.router.core.message.IMSDMessage;
import com.ybt.router.core.message.IMSDMessageConstants;
import com.ybt.router.core.message.factory.IMessageFactory;
import com.ybt.router.core.sender.ISender;
import com.ybt.router.core.sender.manager.ISenderManager;
import com.ybt.router.exception.MessageRouterException;

public class MessageClient {
    private static Logger logger = Logger.getLogger(MessageClient.class);
    private static MessageClient client;

    public static MessageClient getInstance() {
        if (client == null) {
            client = new MessageClient();
        }
        return client;
    }

    /**
     * 以同步方式发送消息，调用后当前线程挂起。 直到接收到返回，或超时
     * 
     * @param body
     *            消息体
     * @param header
     *            消息头部属性
     * @return 返回消息的消息体内容
     */
    public byte[] synSend(byte[] body, Properties header)
            throws MessageRouterException {

        // 初始化同步对象
        SynResponse lock = null;
        synchronized (lock) {
            // 设置同步标记
            header.put(IMSDMessageConstants.MSD_ADMIN_SERVICE_SYNCHRONIZE, "true");

            // 发送消息
            String msgId = sendOneWay(body, header);
            SynResponsePool.getInstance().putResponse(msgId, lock);
            try {
                // 同步消息超时时间
                long waiteTime = YBTRuntimeConfiguration.getInstance().getMessageTimeout();
                // 等待同步返回
                lock.wait(waiteTime);
            } catch (InterruptedException e) {
                // 请求被异常中断
                logger.error(
                        "Occure error when waiting response mesage , message id: "
                                + msgId, e);
                throw new MessageRouterException("等待消息返回时，线程被中断", e);
            } finally {
                // 清空响应消息池
                SynResponsePool.getInstance().removeResponse(msgId);
            }

            // 超时消息和正常返回消息
            if (lock.isReploy()) {
                // 正常返回
                return lock.getReponseBody();
            } else {
                // 超时返回
                throw new MessageRouterException("等待消息返回超时");
            }
        }
    }

    /**
     * 以异步方式方式发送消息，发送消息后，不等待消息返回
     * 
     * @param body
     *            消息体
     * @param header
     *            消息头部属性
     * @return 消息id
     */
    public String sendOneWay(byte[] body, Properties header) throws MessageRouterException {
        IMessageFactory factory = RouterTypeManager.getInstance().getMessageFactory();
        IMSDMessage message = factory.createMessage(body);
        if (header != null) {
            message.setHeader(header);
        }
        message.setMessageBody(body);
        // 设置消息id
        String msgId = UUID.randomUUID().toString();
        message.setMessageID(msgId);
        
        //获取send
        ISenderManager senderManager = RouterTypeManager.getInstance().getSenderManager();
        String serviceName = header.getProperty(IMSDMessageConstants.MSD_DESTINATION);
        ISender sender = senderManager.getSender(serviceName);
        
        //发送
        sender.send(message);
        
        return msgId;

    }
    
}

